package io.gatling.extensions.mongodb.check

import io.gatling.commons.validation._
import io.gatling.core.check._
import io.gatling.extensions.common.check.CommonCheckSupport
import org.mongodb.scala.result.{UpdateResult, _}

trait MongoCheckSupport extends CommonCheckSupport {

  // materializer 的作用是将 R 转为 P，不过我一般直接 R = P
  // 创建隐式 materializer，给 CommonCheckSupport 中的隐式方法使用

  // CheckMaterializer[T, C <: Check[R], R, P]
  implicit val UpdateResultMaterializer: CheckMaterializer[MongoCheckType, Check[UpdateResult], UpdateResult, UpdateResult] = new CheckMaterializer[MongoCheckType, Check[UpdateResult], UpdateResult, UpdateResult](identity) {
    // 这里实际应该用上 type Preparer[R, P] = R => Validation[P] 但是我懒得用了，这样写直接使 P = R
    override protected def preparer: Preparer[UpdateResult, UpdateResult] = _.success
  }

  implicit val InsertOneResultMaterializer: CheckMaterializer[MongoCheckType, Check[InsertOneResult], InsertOneResult, InsertOneResult] = new CheckMaterializer[MongoCheckType, Check[InsertOneResult], InsertOneResult, InsertOneResult](identity) {
    // 这里实际应该用上 type Preparer[R, P] = R => Validation[P] 但是我懒得用了，这样写直接使 P = R
    override protected def preparer: Preparer[InsertOneResult, InsertOneResult] = _.success
  }

  implicit val InsertManyResultMaterializer: CheckMaterializer[MongoCheckType, Check[InsertManyResult], InsertManyResult, InsertManyResult] = new CheckMaterializer[MongoCheckType, Check[InsertManyResult], InsertManyResult, InsertManyResult](identity) {
    // 这里实际应该用上 type Preparer[R, P] = R => Validation[P] 但是我懒得用了，这样写直接使 P = R
    override protected def preparer: Preparer[InsertManyResult, InsertManyResult] = _.success
  }

  implicit val DeleteResultMaterializer: CheckMaterializer[MongoCheckType, Check[DeleteResult], DeleteResult, DeleteResult] = new CheckMaterializer[MongoCheckType, Check[DeleteResult], DeleteResult, DeleteResult](identity) {
    // 这里实际应该用上 type Preparer[R, P] = R => Validation[P] 但是我懒得用了，这样写直接使 P = R
    override protected def preparer: Preparer[DeleteResult, DeleteResult] = _.success
  }

  val matchedCount: FindCheckBuilder[MongoCheckType, UpdateResult, Long] = MatchedCountCheckBuilder

  val modifiedCount: FindCheckBuilder[MongoCheckType, UpdateResult, Long] = ModifiedCountBuilder

  val wasAcknowledgedOne: FindCheckBuilder[MongoCheckType, InsertOneResult, Boolean] = InsertOneCheckBuilder

  val wasAcknowledgedMany: FindCheckBuilder[MongoCheckType, InsertManyResult, Boolean] = InsertManyCheckBuilder

  val deletedCount: FindCheckBuilder[MongoCheckType, DeleteResult, Long] = DeleteCheckBuilder
}
